package muse.probing;

import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.io.*;
import parameters.Parameters;

public class ProxyProbing
{
	private DatagramSocket socket;
	private DataInputStream dais=null;
	private ByteArrayOutputStream baos=null;
	private DataOutputStream daos=null;
	private boolean close = false;
	//Marco: ma a che cosa serve sta roba? probing vuol dire sondare, ma cosa? e che cosa è la disperisione indicata sotto?
	private int dispersion=22; //imposto la prima disperione a 11 ms in modo tale da testare il link a 1 mb/s;
	
	public void probe() throws Exception {
		/*
		 * Datagram socket per ricevere e inviare i pacchetti UDP tramite la porta specificata nella linea di comando
		 */

		socket = new DatagramSocket (Parameters.proxyProbingPort,InetAddress.getLocalHost());
		System.out.println("ProxyProbing Probe: proxyProbing creato in ascolto su "+InetAddress.getLocalHost()+" "+socket.getLocalPort());
		/*
		 * Loop di elaborazione.
		 */ 
		while (!close)
		{
			//System.out.println("ProxyProbing probe: loop di elaborazione iniziato");
			DatagramPacket request = new DatagramPacket (new byte[1470], 1470);
			socket.receive (request);
			//System.out.println(request.getAddress());
			

			/*
			 * Invio risposta.
			 */ 
			InetAddress clientHost = request.getAddress ();
			int clientPort = request.getPort ();
			byte[]buf = request.getData ();
			extractDispersion(buf);
			
			
			DatagramPacket reply = new DatagramPacket (new byte[1470], 1470, clientHost, clientPort);
			socket.send (reply);
			Thread.sleep( dispersion);
			socket.send(reply);
			
			//System.out.println (" Reply sent.");
		}
		System.out.println("ProxyProbing Probe: termino loop di elaborazione ProxyProbing");
	}
	
	private void extractDispersion(byte []buf){
		dais= new DataInputStream(new ByteArrayInputStream(buf));
		try {
			dispersion= dais.readInt();
			//System.out.println("ProxyProbing ExtractDispersion: "+dispersion);
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
	
	public void close(){
		close=true;
		socket.close();
	}
	
}
